<template>
  <div style="width: 100%">
    <el-collapse v-model="activeName">
      <el-collapse-item title="基本信息" name="1">
        <el-form ref="form" size="small" :disabled="disabled" :model="formData" :rules="rules"
                 label-width="100px">
          <el-row>
            <el-col :span="12">
              <el-form-item label="中文名称：" prop="nameCn">
                <el-input v-model="formData.nameCn"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="实体类型：" prop="typeName">
                <el-select-tree style="width: 100%"
                                :options="latestList"
                                v-model="formData.typeName"
                                :disabled="drawerType!=='open'"
                                @change="changeVal('typeCode')"
                                @input="getRelation(),getAttributeList()">
                </el-select-tree>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="12">
              <el-form-item label="编码标识：" prop="name">
                <el-input :disabled="drawerType!=='open'" v-model="formData.name"></el-input>
              </el-form-item>
            </el-col>

            <el-col :span="12">
              <el-form-item label="英文名称：" prop="nameEn">
                <el-input v-model="formData.nameEn"></el-input>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="24">
              <el-form-item label="英文描述：" prop="describeEn">
                <el-input v-model="formData.describeEn"></el-input>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="24">
              <el-form-item label="中文描述：" prop="describeCn">
                <el-input v-model="formData.describeCn"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </el-collapse-item>
      <el-collapse-item title="条件规则" name="2">
        <avue-crud :option="option"
                   :table-loading="loading"
                   :data="tableData"
                   ref="crud">
          <template slot="menuLeft">
            <el-button :disabled="disabled"
                       type="primary"
                       size="small"
                       @click="tableAdd('1')">
              添加行
            </el-button>
            <el-button
                :disabled="disabled"
                type="primary"
                size="small"
                @click="tableAdd('2')">
              添加分组
            </el-button>
          </template>
          <template slot="refCode" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <span class="l2">关系 </span>
              <el-select :disabled="disabled" clearable size="mini" v-model="row.refCode"
                         @change="changeVal('refCode',row.$index)"
                         @input="getAttributeList(row.$index+'')">
                <template v-for="{name,nameCn} in  relationList">
                  <el-option :label="nameCn" :value="name"></el-option>
                </template>
              </el-select>
            </div>
            <div class="columnClass" v-if="!showCon(row)">
              <span class="l2">分组 </span>
              <el-select :disabled="disabled" size="mini" v-model="row.connect">
                <el-option value="AND" label="与"></el-option>
                <el-option value="OR" label="或"></el-option>
              </el-select>
            </div>
          </template>
          <template slot="toCode" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <span>关联类型 </span>
              <el-select :disabled="disabled" clearable size="mini" v-model="row.toCode"
                         @change="changeVal('toCode',row.$index)"
                         @input="getAttributeList(row.$index+'')">
                <template v-for="{name,nameCn} in  getToCodeList(row.refCode)">
                  <el-option :label="nameCn" :value="name"></el-option>
                </template>
              </el-select>
            </div>
            <div class="columnClass" v-if="!showCon(row)">
              <el-button :disabled="disabled" type="text" style="font-size: 20px;padding: 0"
                         icon="el-icon-error"
                         @click="delLine(row)"></el-button>
            </div>
          </template>
          <template slot="attributeId" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <span>属性字段 </span>
              <el-select :disabled="disabled" size="mini" v-model="row.attributeId"
                         @change="row.value=''">
                <template v-for="{oid,nameCn} in row.attributeList">
                  <el-option :label="nameCn" :value="oid"></el-option>
                </template>
              </el-select>
            </div>
          </template>
          <template slot="symbol" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <span class="l3">判断符 </span>
              <el-select :disabled="disabled" size="mini" v-model="row.symbol"
                         @change="row.value='',getEnum(row)">
                <el-option label="==" value="=="></el-option>
                <el-option label="!=" value="!="></el-option>
                <el-option label=">" value=">"></el-option>
                <el-option label="<" value="<"></el-option>
                <el-option label=">=" value=">="></el-option>
                <el-option label="<=" value="<="></el-option>
                <template v-if="!['time','date','datetime'].includes(setValueTemp(row))">
                  <el-option label="IN" value="IN"></el-option>
                  <el-option label="NOTIN" value="NOTIN"></el-option>
                </template>
              </el-select>
            </div>
          </template>
          <template slot="value" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <span class="l1">值 </span>
              <template v-if="!['IN','NOTIN'].includes(row.symbol)">
                <el-input v-if="!['time','date','datetime'].includes(setValueTemp(row))"
                          :disabled="disabled" size="mini"
                          v-model="row.value">
                </el-input>

                <el-time-picker
                    size="mini"
                    v-model="row.value"
                    value-format="HH:mm:ss"
                    v-if="setValueTemp(row)==='time'"
                    placeholder="请选择时间">
                </el-time-picker>

                <el-date-picker
                    size="mini"
                    type="date"
                    v-model="row.value"
                    value-format="yyyy-MM-dd 00:00:00"
                    v-if="setValueTemp(row)==='date'"
                    placeholder="请选择日期">
                </el-date-picker>

                <el-date-picker
                    size="mini"
                    v-model="row.value"
                    type="datetime"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    v-if="setValueTemp(row)==='datetime'"
                    placeholder="请选择日期时间">
                </el-date-picker>
              </template>

              <template v-else>
                <el-select size="mini" style="width: 40% !important"
                           :disabled="disabled" v-model="row.value" @change="getEnum(row)">
                  <template v-for="i in enumData">
                    <el-option :value="i.name" :label="i.nameCn"></el-option>
                  </template>
                </el-select>
                <el-select :key="row.value" size="mini" style="width: 60% !important" multiple collapse-tags
                           :disabled="disabled" v-model="row.enumValue">
                  <template v-for="item in row.enumData">
                    <el-option :label="item.name" :value="item.value"></el-option>
                  </template>
                </el-select>
              </template>
            </div>
          </template>
          <template slot="connect" slot-scope="{row}">
            <div class="columnClass" v-if="showCon(row)">
              <el-select :disabled="disabled?true:disabledConnect(row)"
                         size="mini"
                         v-model="row.connect">
                <el-option value="AND" label="与"></el-option>
                <el-option value="OR" label="或"></el-option>
              </el-select>&nbsp;
              <span class="l1">
                <el-button type="text"
                           :disabled="disabled"
                           style="font-size: 20px;padding: 0"
                           icon="el-icon-error"
                           @click="delLine(row)">
                </el-button>
              </span>
            </div>
          </template>
        </avue-crud>
      </el-collapse-item>
    </el-collapse>
    <div class="md-component-btns">
      <el-button size="medium"
                 type="primary"
                 v-if="drawerType!=='view'"
                 @click="save">
        保存
      </el-button>
      <el-button size="medium" @click="$emit('removeThisTabs')">取消</el-button>
    </div>
  </div>
</template>

<script>
import * as api from "@/api/configuration/condition";
import ElSelectTree from "@/components/el-select-tree.vue";
import * as enumApi from "@/api/modulManage/enum";
import {getDic} from "@/api/common";

export default {
  name: "conditionTemp",
  components: {ElSelectTree},
  data() {
    return {
      activeName: ["1", "2"],

      rules: {
        name: [{
          required: true,
          trigger: 'blur',
          message: "请输入编码标识"
        }, {pattern: '^[A-Za-z][A-Za-z0-9_]{1,29}$', message: '请输入正确编码标识'}],
        nameCn: [{required: true, trigger: 'blur', message: "请输入中文名称"}],
        // nameEn: [{required: true, trigger: 'blur', message: "请输入英文名称"}],
        describeCn: [{required: true, trigger: 'blur', message: "请输入中文描述"}],
        // describeEn: [{required: true, trigger: 'blur', message: "请输入英文描述"}],
        typeName: [{required: true, trigger: 'change', message: "请选择实体类型"}],
      },
      formData: {
        name: "",
        nameCn: "",
        nameEn: "",
        describeCn: "",
        describeEn: "",
        typeName: "",
        policyConditionRuleList: []
      },

      tableData: [],
      option: {
        height: "auto",
        calcHeight: 30,
        dialogWidth: 900,
        tip: false,
        searchShow: true,
        searchMenuSpan: 6,
        border: false,
        index: false,
        selection: false,
        labelWidth: 120,
        menuWidth: 200,
        viewBtn: false,
        dialogClickModal: false,
        tabs: true,
        delBtn: false,
        addBtn: false,
        editBtn: false,
        refreshBtn: false,
        columnBtn: false,
        align: "center",
        showHeader: false,
        menu: false,
        highlightCurrentRow: false,
        column: [
          {label: "关系", prop: "refCode", width: 200, formSlot: "refCode"},
          {label: "关联类型", prop: "toCode", width: 260, formSlot: "toCode"},
          {label: "属性字段", prop: "attributeId", width: 230, formSlot: "attributeId"},
          {label: "判断符", prop: "symbol", width: 190, formSlot: "symbol"},
          {label: "值", prop: "value", width: 300, formSlot: "value"},
          {label: "", prop: "connect", width: 120, formSlot: "connect"},
        ]
      },
      loading: false,

      latestList: [],
      relationList: [],
      attributeList: [],

      drawerType: "open",

      enumData: []
    }
  },
  computed: {
    disabled() {
      return this.drawerType === "view";
    }
  },
  methods: {
    getEnum(row) {
      if (['IN', 'NOTIN'].includes(row.symbol) && row.value) {
        row.enumValue = [];
        getDic(row.value).then(res => {
          this.$set(this.tableData[row.$index], "enumData", res.data.data)
        });
      }
    },
    setValueTemp(row) {
      let id = row.attributeId;
      let list = row.attributeList;
      if (id && list && list.length > 0) {
        let obj = list.filter(i => i.oid === id);
        return obj[0] ? obj[0].columnType : 'string';
      }
    },
    disabledConnect(row) {
      if (row.$index === this.tableData.length - 1) {
        return true
      }
      if (this.tableData[row.$index + 1]) {
        return this.tableData[row.$index + 1].type == "2";
      }
      return false;
    },

    changeVal(type, index) {
      if (type === "refCode") {
        this.tableData[index].toCode = "";
        this.tableData[index].attributeId = "";
      }
      if (type === "toCode") {
        this.tableData[index].attributeId = "";
      }
      if (type === "typeCode") {
        this.tableData = [];
      }
    },
    getAttributeList(index) {
      let params = {refType: "1", typeName: this.formData.typeName};
      if (index !== undefined) {
        let {refCode, toCode} = this.tableData[index];
        params = {
          refType: toCode ? "1" : (refCode ? "2" : "1"),
          typeName: toCode ? toCode : (refCode ? refCode : this.formData.typeName)
        };
      }

      api.attributeList(params).then(res => {
        if (index !== undefined) {
          this.$set(this.tableData[index], "attributeList", res.data.data)
        } else {
          this.attributeList = res.data.data
          if (this.tableData.length > 0) {
            let tableData = this.deepCopy(this.tableData);
            this.tableData = [];
            tableData.forEach(i => {
              Object.assign(i, {attributeList: res.data.data});
            })
            this.tableData = tableData;
          }
        }
      })
    },
    getToCodeList(code) {
      let d = this.relationList.filter(i => i.name === code);
      if (d && d.length > 0) {
        return d[0].relateTypeVoList;
      }
      return []
    },

    getRelation() {
      api.getRelation({typeName: this.formData.typeName}).then(res => {
        this.relationList = res.data.data;
      })
    },
    save() {
      this.$refs.form.validate(f => {
        if (f) {
          if (this.tableData.length > 0) {
            if (this.tableData[this.tableData.length - 1].type == "2" || this.tableData[0].type == "2") {
              this.$message.warning("分组不能为第一个或最后一个")
            } else {
              //判断连接符是否正常
              let err = [];
              //判断必填内容是否为空
              let null_ = [];
              //判断是否存在相邻分组
              let group = [];
              this.tableData.forEach((i, ix) => {
                let j = {};
                if (this.tableData[ix + 1]) {
                  j = this.tableData[ix + 1];
                }

                if (JSON.stringify(j) !== "{}") {
                  if (j.type != "2" && !i.connect) {
                    err.push(i);
                  }
                  if (i.type == "2" && j.type == "2") {
                    group.push(`第${ix + 1}行和第${ix + 2}行`)
                  }
                }

                if (!i.attributeId || !i.symbol || !i.value) {
                  if (i.type != "2") {
                    null_.push(ix + 1);
                  }
                }
              })

              if (null_.length > 0) {
                this.$message.warning(`第${null_.join(",")}行 属性字段｜判断符｜值为空`);
              } else {
                if (err.length > 0) {
                  let connect = err.map(i => i.$index + 1).join(",");
                  this.$message.warning(`第${connect}行连接符必填`);
                } else {
                  if (group.length > 0) {
                    this.$message.warning(`${group.join(",")}，相邻行不可同为分组`);
                  } else {
                    this.formData.policyConditionRuleList = this.deepCopy(this.tableData)

                    this.formData.policyConditionRuleList.forEach(item => {

                      let {attributeList, attributeId} = item;
                      let ids = attributeList.map(i => i.oid);
                      Object.assign(item, {attributeName: attributeList[ids.indexOf(attributeId)].columnName})

                      if (item.enumValue && item.enumValue.length > 0) {
                        item.enumValue = item.enumValue.join(",");
                      }
                      if (item.enumValue && item.enumValue.length === 0) {
                        delete item.enumValue
                      }
                      if (item.enumData && item.enumData.length === 0) {
                        delete item.enumData
                      }
                    })

                    let methods = this.drawerType === "open" ? "save" : "update";
                    api[methods](this.formData).then(() => {
                      this.$message.success("保存成功");
                      this.$emit('refresh');
                      this.$emit('removeThisTabs');
                    })
                  }
                }
              }
            }
          } else {
            this.formData.policyConditionRuleList = [];
            this.formData.ruleJson = "";
            let methods = this.drawerType === "open" ? "save" : "update";
            api[methods](this.formData).then(() => {
              this.$message.success("保存成功");
              this.$emit('refresh');
              this.$emit('removeThisTabs');
            })
          }
        }
      })
    },
    delLine(row) {
      this.tableData.splice(row.$index, 1);

      this.tableData.forEach((i, ix) => {
        let j = {};
        if (this.tableData[ix + 1]) {
          j = this.tableData[ix + 1];
        }

        if (JSON.stringify(j) !== "{}") {
          if (j.type == "2" && i.type == "1") {
            i.connect = ""
          }
        } else {
          if (i.type == "1") {
            i.connect = ""
          }
        }

      })
    },
    showCon(row) {
      return row.type != "2";
    },
    tableAdd(type) {
      if (type === "1") {
        this.tableData.push({
          refCode: "",
          toCode: "",
          attributeId: "",
          symbol: "",
          value: "",
          enumValue: [],
          enumData: [],
          attributeList: this.deepCopy(this.attributeList),
          connect: "",
          type
        })
      } else {
        this.tableData.push({type, connect: ""})
      }

    },
    details(res) {
      let data = res.data.data;
      this.formData = this.deepCopy(data);
      this.getRelation();
      this.tableData = this.deepCopy(data.policyConditionRuleList)
      this.getAttributeList();
      if (this.tableData.length > 0) {
        this.tableData.forEach((i, index) => {
          this.getAttributeList(index);
          if (['IN', 'NOTIN'].includes(i.symbol) && i.value) {
            i.enumValue = i.enumValue.split(",")
            getDic(i.value).then(res => {
              i.enumData = res.data.data
            });
          }
        })
      }
    },
    open() {
      this.drawerType = "open"
    },
    edit(row) {
      this.drawerType = "edit"
      api.checkout({id: row.oid}).then(res => {
        this.details(res);
        this.$emit('refresh');
      })

    },
    view(row) {
      this.drawerType = "view"
      api.detail({id: row.oid}).then(res => {
        this.details(res);
      })
    }
  },
  mounted() {
    api.latest().then(res => {
      this.latestList = res.data.data;
    })
    enumApi.getListData().then(res => {
      this.enumData = res.data.data;
    })
  }
}
</script>
<style scoped lang="scss">
.columnClass {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  flex-wrap: nowrap;

  > span {
    width: 90px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    text-align: right;
    padding-right: 5px;
  }

  .l1 {
    width: 30px;
  }

  .l2 {
    width: 50px;
  }

  .l3 {
    width: 70px;
  }
}
</style>
